#define PI	3.14159265
#define OCTAVES 3
#define PERSISTENCE 1

float raw_noise(int x, int y, int random);
float cosine_1D_interpolate(float a,float b, float x);
float smoothed_2D_noise(int x,int y, int random);
float cosine_2D_noise(float x,float y,int random);
float perlin_2D_noise(float x, float y, int random);

struct appdata //allvarligt. det här får mig att hata.
{
	float4 position : POSITION;
	float4 color	: COLOR0;
	float3 wave	: COLOR1;
	float2 texcoord : TEXCOORD0;
};

struct vfconn
{
	float4 HPos	: POSITION;
	float4 Col0	: COLOR0;
	float2 Tex	: TEXCOORD0;
};

float perlin_2D_noise(float x, float y, int random) {
	int i;
	float frequency,amplitude;
	float total = 0;
	int p = PERSISTENCE;
	int n = OCTAVES-1;
	for(i=0;i<(int)n;i++) {
		frequency = 2^i;
		amplitude = p^i;
		total+=cosine_2D_noise(x*frequency,y*frequency,random)*amplitude;
	}
	return total;
}

float raw_noise(int x, int y, int random) {
	float ret;
    int n = x + y * 57 + random * 131;
    n = (n<<13) ^ n;
    ret = (1.0f - ( (n * (n * n * 15731 + 789221) + 1376312589)&0x7fffffff)* 0.000000000931322574615478515625f);
	return ret;
}

float cosine_1D_interpolate(float a,float b, float x) {
	float ft,f,ret;
	ft = x * PI;
	f = (1 - cos(ft)) * 0.5;
	ret =  a*(1-f)+ b*f;
	return (float) ret;
}

float smoothed_2D_noise(int x,int y, int random) {
	float ret,corners,sides,center;
	corners = ( raw_noise(x-1, y-1,random)+raw_noise(x+1, y-1,random)+raw_noise(x-1, y+1,random)+raw_noise(x+1, y+1,random) ) / 16;
	sides   = ( raw_noise(x-1, y,random)  +raw_noise(x+1, y,random)  +raw_noise(x, y-1,random)  +raw_noise(x, y+1,random) ) /  8;
	center  =  raw_noise(x, y,random) / 4;
	ret = corners + sides + center;
	return ret;
}

float cosine_2D_noise(float x,float y,int random) {
	float ret;
	int intyfied_x = (int) x;
	float fractional_x = x - intyfied_x;
	
	int intyfied_y = (int) y;
	float fractional_y = y - intyfied_y;

	float v1,v2,v3,v4,i1,i2;
	v1 = smoothed_2D_noise(intyfied_x,intyfied_y, random);
	v2 = smoothed_2D_noise(intyfied_x+1,intyfied_y, random);
	v3 = smoothed_2D_noise(intyfied_x,intyfied_y+1, random);
	v4 = smoothed_2D_noise(intyfied_x+1,intyfied_y+1, random);

	i1 = cosine_1D_interpolate(v1,v2,fractional_x);
	i2 = cosine_1D_interpolate(v3,v4,fractional_x);

	ret = cosine_1D_interpolate(i1,i2, fractional_y);
	return ret;
}

vfconn main(appdata IN,	uniform float4x4 ModelViewProj,uniform sampler2D texture : TEXUNIT0) {
	vfconn OUT;
	IN.position.y = perlin_2D_noise(IN.position.x+IN.wave.x,IN.position.z+IN.wave.x,1337)*0.2 + (sin(IN.position.x+IN.position.z+IN.wave.x)*0.05);
	IN.position.y += perlin_2D_noise(IN.position.x+(IN.wave.x*0.9),IN.position.z+(IN.wave.x*0.9),1337)*0.09;
	IN.position.y *= 0.9;
	OUT.HPos = mul(ModelViewProj, IN.position);
	OUT.Col0 = IN.color;
	OUT.Tex = IN.texcoord;
	//OUT.Col0 += tex2D(texture,IN.texcoord).rgba;
	return OUT;
}
